package com.yxf.variousshapes;

import android.content.Context;
import android.opengl.GLSurfaceView;

import com.yxf.variousshapes.shapes.Polygon;
import com.yxf.variousshapes.shapes.Ring;
import com.yxf.variousshapes.shapes.Shape;
import com.yxf.variousshapes.shapes.Square;
import com.yxf.variousshapes.shapes.Star;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import static android.opengl.GLES20.*;
import static android.opengl.Matrix.orthoM;

public class MyRenderer implements GLSurfaceView.Renderer {

    private static final String A_POSITION = "a_Position";
    private int aPositionLocation;

    private static final String U_MATRIX = "u_Matrix";
    private final float[] projectionMatrix = new float[16];
    private int uMatrixLocation;

    private static final String A_COLOR = "a_Color";
    private int aColorLocation;

    private Context context;
    private int program;

    //1,定义图形容器,SurfaceView是多线程的,所以使用线程安全的CopyOnWriteArrayList
    private List<Shape> shapeList = new CopyOnWriteArrayList<Shape>();


    public MyRenderer(Context context) {
        this.context = context;
    }

    public void addShape(Shape shape) {
        shapeList.add(shape);
    }


    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        glClearColor(0f, 1f, 0f, 0f);

        String vertexShaderSource = CommonUtils.readTextFromResource(context, R.raw.shape_vertex_shader);
        String fragmentShaderSource = CommonUtils.readTextFromResource(context, R.raw.shape_fragment_shader);
        int vertexShader = CommonUtils.compileVertexShader(vertexShaderSource);
        int fragmentShader = CommonUtils.compileFragmentShader(fragmentShaderSource);
        program = CommonUtils.linkProgram(vertexShader, fragmentShader);
        glUseProgram(program);
        aPositionLocation = glGetAttribLocation(program, A_POSITION);
        uMatrixLocation = glGetUniformLocation(program, U_MATRIX);
        aColorLocation = glGetAttribLocation(program, A_COLOR);

        glEnableVertexAttribArray(aPositionLocation);
        glEnableVertexAttribArray(aColorLocation);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        glViewport(0, 0, width, height);
        final float aspectRatio = height / (float) width;
        orthoM(projectionMatrix, 0, -1, 1, -aspectRatio, aspectRatio, -1, 1);

        initShapeList(aspectRatio);
    }

    private void initShapeList(float aspectRatio) {
        shapeList.clear();
        //正方形
        //addShape(new Square(new Point(-0.5f, aspectRatio * 2 / 3, 0), 0.4f, 0.4f));
        //圆
        addShape(new Polygon(new Point(0.5f, aspectRatio * 2 / 3, 0), 0.2f, 360));
        //正五边形
        addShape(new Polygon(new Point(-0.5f, 0, 0), 0.2f, 5));
        //正六边形
        addShape(new Polygon(new Point(0.5f, 0, 0), 0.2f, 6));
        //正八边形
        //addShape(new Polygon(new Point(-0.5f, -aspectRatio * 2 / 3, 0), 0.2f, 8));
        //圆环
        addShape(new Ring(new Point(-0.5f, -aspectRatio * 2 / 3, 0), 0.2f, 0.03f));
        //正五角星
        addShape(new Star(new Point(0.5f, -aspectRatio * 2 / 3, 0), 0.4f, 5));
        //正六角星
        addShape(new Star(new Point(-0.5f, aspectRatio * 2 / 3, 0), 0.4f, 6));
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        glClear(GL_COLOR_BUFFER_BIT);
        glUniformMatrix4fv(uMatrixLocation, 1, false, projectionMatrix, 0);
        for (Shape shape : shapeList) {
            shape.setLocation(aPositionLocation, aColorLocation);
            shape.draw();
        }
    }
}
